﻿#ifndef OSGWIDGET_H
#define OSGWIDGET_H

#include <QtWidgets>
#include <osg/Node>
#include <osgQt/GraphicsWindowQt>
#include <osgViewer/Viewer>
#include <osg/Geode>
#include <osg/Group>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
#include <global.h>         // Triangle Point Axis
#include <Eigen/Dense>

class ReadThread;

class OsgWidget : public QWidget
{
        Q_OBJECT

    public:

        explicit OsgWidget(QWidget *parent = 0);

        virtual ~OsgWidget();

        bool addjoint(const QString& fileName);

        bool addObject(const QString& fileName);

        bool removeJoint();

        bool removeObject();

        bool rotateBySelfToTargetAngle(const JointType& joint, const double& targetAngle);

        bool setHideAxisMode(const bool& isOpen);

        bool moveJ(const Joint& beginJoint, const Joint& endJoint);

        bool moveLine(const Joint& beginJoint, const Joint& endJoint);

        void drawLine(Eigen::Vector3d p1, Eigen::Vector3d p2) const ;

        /** 在点坐标处渲染一个球 */
        void drawPoint(const osg::Vec3d& point);

        void removeShadow();

        void removePath() const;

        QString assembleTool();

        std::string buildBox(const std::vector<float>& boxInfo);
        std::string buildBall(const float& radius);
        std::string buildCylinder(const std::vector<float>& cylinderInfo);

    signals:

        void isMoveFinished();

        void runNewThread1(QString);
        void runNewThread2(QString);
        void runNewThread3(QString);
        void runNewThread4(QString);
        void runNewThread5(QString);

        void readFinished();

    public slots:

        void setCurrentJointText(QString text);

        void setCurrentObjectText(QString text);

        void moveAllJoint();

        void drawOneShadow();

        void recvFile(NodeInfo);

        void loadFile();


    protected:

        inline void resizeEvent(QResizeEvent* event) {
            Q_UNUSED(event);
            update();
        }

        inline void paintEvent( QPaintEvent* event ) {
            Q_UNUSED(event);
            (*pViewer).frame();
        }

    private:

        void initOsg();

        void layout();

        bool isEnd();

        osgQt::GraphicsWindowQt* createGraphicsWindow(int x, int y, int w, int h);

        osg::ref_ptr<osg::Group> makeCoordinate(const float& len);

        bool rotateBySelfWithAngle(const JointType& joint, const double& targetAngle);

        void rotateBySelf(const JointType& joint, osg::Matrix& curMatrix, const osg::Vec3d& offset, const float& angle);

        osg::ref_ptr<osg::Geode> createCircle(const std::string name, const float& radius, const osg::Vec4& color);

        osg::Vec3d getOffset(const JointType& joint);



    private:

        std::list<osg::ref_ptr<osg::MatrixTransform>> jointMatrifromList;

        std::vector<osg::ref_ptr<osg::Node>> nodesBuffer;

        std::vector<NodeInfo> nodeInfoBuffer;

        osg::ref_ptr<osgViewer::Viewer> pViewer;

        osg::ref_ptr<osgQt::GraphicsWindowQt> pWindow;

        osg::ref_ptr<osg::Group> pGroup;

        QTimer timer;
        QTimer While;       // 用timer代替while循环
        QTimer drawTimer;   // 用timer代替while循环

        int curIndex;

        QString curJointText;
        QString curObjectText;

        int pRear;

        std::vector<ReadThread*> readHandle;
        std::vector<QThread*> threadPool;    /// 线程池


};

#endif // OSGWIDGET_H
